package com.gome.ocean.service.zookeeper.service;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gome.framework.util.SystemInfoUtil;
import com.gome.ocean.common.constants.ZkContants;
import com.gome.ocean.service.zookeeper.balancer.LoadBalancer;
import com.gome.ocean.service.zookeeper.client.ZkClient;
import com.gome.ocean.service.zookeeper.listener.ChildListener;

@Component("zkService")
public class ZkServiceFactory implements ZkService, InitializingBean, DisposableBean {

    private List<String>        dataxServices = new CopyOnWriteArrayList<String>();

    private static final Logger logger        = LoggerFactory.getLogger(ZkServiceFactory.class);

    @Autowired
    private ZkClient            zkClient;

    @Autowired
    private LoadBalancer        loadBalancer;

    @Override
    public void destroy() throws Exception {
        dataxServices.clear();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        pubService();
        subService();
    }

    /**
     * 初始化服务
     */
    private void subService() {
        List<String> services = zkClient.getChildren(ZkContants.SERVICES);
        if (!services.isEmpty()) {
            dataxServices.addAll(services);
        }
        zkClient.addChildListener(ZkContants.SERVICES, new ChildListener() {
            @Override
            public void childChanged(String path, List<String> children) {
                dataxServices.clear();
                if(!children.isEmpty()){
                    logger.info("discover service service :" + children);
                    dataxServices.addAll(children);
                }
            }
        });
        logger.info("init service is complete!");
    }

    /**
     * 发布服务
     */
    private void pubService() {
        String port = SystemInfoUtil.getServerPort();
        String ip = SystemInfoUtil.getLocalAddress();
        StringBuffer pubService = new StringBuffer();
        pubService.append(ZkContants.SERVICES).append("/").append(ip).append(":").append(port);
        zkClient.create(pubService.toString(), true, false);
        logger.info("pub service ! ip:" + ip + ",port:" + port);
    }

    @Override
    public String getService() {
        if(CollectionUtils.isEmpty(dataxServices)){
            return null;
        }
        return loadBalancer.getService(dataxServices);
    }
}
